using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.IO;
using System.Collections.Generic;
using System.Net;

namespace StatisticsStrategy
{
    public struct Company
    {
        public string code;
        public string name;
    }

    public struct Session
    {
        public float max;
        public float min;
        public float close;
        public int volume;
        public DateTime date;
    }
	/// <summary>
	/// Summary description for ctlMain.
	/// </summary>
	public class ctlMain : System.Windows.Forms.UserControl
    {
        private ListViewColumnSorter lvwColumnSorter;
        private List<string> lstFavoriteCodes;
        private string sListFavoritePath;
        private WebClient webClient;
        private int iMode;
        private string currency;
        private int nMarket;
        private string[] MarketNames;
        private string[] PriceBoardServices;
        private ComboBox cbMarkets;
        private ListView lvStatistic;
        private Button btnStatistic;
        private DateTimePicker dtpFrom;
        private DateTimePicker dtpTo;
        private IContainer components;
        private List<float> lstAmplitude;
        private ColumnHeader chCode;
        private ColumnHeader chUp;
        private ColumnHeader chPercentUp;
        private ColumnHeader chCeil;
        private ColumnHeader chPercentCeil;
        private ColumnHeader chStable;
        private ColumnHeader chPercentStable;
        private ColumnHeader chDown;
        private ColumnHeader chPercentDown;
        private ColumnHeader chFloor;
        private ColumnHeader chPercentFloor;
        private ColumnHeader chUpReversal;
        private ColumnHeader chDownReversal;
        private ColumnHeader chSession;
        private List<Company> lstCompanies;

		public ctlMain()
		{
			// This call is required by the Windows.Forms Form Designer.
			InitializeComponent();

			// TODO: Add any initialization after the InitializeComponent call

		}

		/// <summary> 
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Component Designer generated code
		/// <summary> 
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
            this.cbMarkets = new System.Windows.Forms.ComboBox();
            this.lvStatistic = new System.Windows.Forms.ListView();
            this.chCode = new System.Windows.Forms.ColumnHeader();
            this.chUp = new System.Windows.Forms.ColumnHeader();
            this.chPercentUp = new System.Windows.Forms.ColumnHeader();
            this.chCeil = new System.Windows.Forms.ColumnHeader();
            this.chPercentCeil = new System.Windows.Forms.ColumnHeader();
            this.chStable = new System.Windows.Forms.ColumnHeader();
            this.chPercentStable = new System.Windows.Forms.ColumnHeader();
            this.chDown = new System.Windows.Forms.ColumnHeader();
            this.chPercentDown = new System.Windows.Forms.ColumnHeader();
            this.chFloor = new System.Windows.Forms.ColumnHeader();
            this.chPercentFloor = new System.Windows.Forms.ColumnHeader();
            this.chUpReversal = new System.Windows.Forms.ColumnHeader();
            this.btnStatistic = new System.Windows.Forms.Button();
            this.dtpFrom = new System.Windows.Forms.DateTimePicker();
            this.dtpTo = new System.Windows.Forms.DateTimePicker();
            this.chDownReversal = new System.Windows.Forms.ColumnHeader();
            this.chSession = new System.Windows.Forms.ColumnHeader();
            this.SuspendLayout();
            // 
            // cbMarkets
            // 
            this.cbMarkets.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.cbMarkets.FormattingEnabled = true;
            this.cbMarkets.Location = new System.Drawing.Point(16, 16);
            this.cbMarkets.Name = "cbMarkets";
            this.cbMarkets.Size = new System.Drawing.Size(92, 21);
            this.cbMarkets.TabIndex = 4;
            // 
            // lvStatistic
            // 
            this.lvStatistic.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
            this.chCode,
            this.chUp,
            this.chPercentUp,
            this.chCeil,
            this.chPercentCeil,
            this.chStable,
            this.chPercentStable,
            this.chDown,
            this.chPercentDown,
            this.chFloor,
            this.chPercentFloor,
            this.chUpReversal,
            this.chDownReversal,
            this.chSession});
            this.lvStatistic.Location = new System.Drawing.Point(16, 53);
            this.lvStatistic.Name = "lvStatistic";
            this.lvStatistic.Size = new System.Drawing.Size(888, 357);
            this.lvStatistic.TabIndex = 5;
            this.lvStatistic.UseCompatibleStateImageBehavior = false;
            this.lvStatistic.View = System.Windows.Forms.View.Details;
            this.lvStatistic.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.lvStatistic_ColumnClick);
            // 
            // chCode
            // 
            this.chCode.Text = "Code";
            // 
            // chUp
            // 
            this.chUp.Text = "Up";
            // 
            // chPercentUp
            // 
            this.chPercentUp.Text = "% Up";
            // 
            // chCeil
            // 
            this.chCeil.Text = "Ceil";
            // 
            // chPercentCeil
            // 
            this.chPercentCeil.Text = "% Ceil";
            // 
            // chStable
            // 
            this.chStable.Text = "Stable";
            // 
            // chPercentStable
            // 
            this.chPercentStable.Text = "% Stable";
            // 
            // chDown
            // 
            this.chDown.Text = "Down";
            // 
            // chPercentDown
            // 
            this.chPercentDown.Text = "% Down";
            // 
            // chFloor
            // 
            this.chFloor.Text = "Floor";
            // 
            // chPercentFloor
            // 
            this.chPercentFloor.Text = "% Floor";
            // 
            // chUpReversal
            // 
            this.chUpReversal.Text = "# Up Rev";
            // 
            // btnStatistic
            // 
            this.btnStatistic.Location = new System.Drawing.Point(372, 15);
            this.btnStatistic.Name = "btnStatistic";
            this.btnStatistic.Size = new System.Drawing.Size(75, 23);
            this.btnStatistic.TabIndex = 6;
            this.btnStatistic.Text = "Statistic";
            this.btnStatistic.UseVisualStyleBackColor = true;
            this.btnStatistic.Click += new System.EventHandler(this.btnStatistic_Click);
            // 
            // dtpFrom
            // 
            this.dtpFrom.Format = System.Windows.Forms.DateTimePickerFormat.Short;
            this.dtpFrom.Location = new System.Drawing.Point(134, 17);
            this.dtpFrom.Name = "dtpFrom";
            this.dtpFrom.Size = new System.Drawing.Size(106, 20);
            this.dtpFrom.TabIndex = 7;
            this.dtpFrom.Value = new System.DateTime(2010, 9, 1, 0, 0, 0, 0);
            // 
            // dtpTo
            // 
            this.dtpTo.Format = System.Windows.Forms.DateTimePickerFormat.Short;
            this.dtpTo.Location = new System.Drawing.Point(246, 17);
            this.dtpTo.Name = "dtpTo";
            this.dtpTo.Size = new System.Drawing.Size(106, 20);
            this.dtpTo.TabIndex = 8;
            // 
            // chDownReversal
            // 
            this.chDownReversal.Text = "# Down Rev";
            // 
            // chSession
            // 
            this.chSession.Text = "# Session";
            // 
            // ctlMain
            // 
            this.BackColor = System.Drawing.Color.White;
            this.Controls.Add(this.dtpTo);
            this.Controls.Add(this.dtpFrom);
            this.Controls.Add(this.btnStatistic);
            this.Controls.Add(this.lvStatistic);
            this.Controls.Add(this.cbMarkets);
            this.Name = "ctlMain";
            this.Size = new System.Drawing.Size(907, 425);
            this.Load += new System.EventHandler(this.ctlMain_Load);
            this.ResumeLayout(false);

		}
		#endregion

		private void ctlMain_Load(object sender, System.EventArgs e)
		{
            this.lstAmplitude = new List<float>();
            this.lstCompanies = new List<Company>();
            this.lvwColumnSorter = new ListViewColumnSorter();
            this.lvStatistic.ListViewItemSorter = lvwColumnSorter;
            this.dtpFrom.Value = this.dtpFrom.Value.Add(new TimeSpan(-30, 0, 0, 0));
            // Initialize config
            StreamReader sr = new StreamReader("config.txt");
            while (!sr.EndOfStream)
            {
                switch (sr.ReadLine().Normalize())
                {
                    case "[currency]":
                        currency = sr.ReadLine().Trim();
                        break;
                    case "[nMarkets]":
                        nMarket = int.Parse(sr.ReadLine());
                        PriceBoardServices  = new string[nMarket];
                        MarketNames = new string[nMarket];
                        for (int i = 0; i < nMarket; i++)
                        {
                            MarketNames[i] = sr.ReadLine().Trim();
                            PriceBoardServices[i] = sr.ReadLine().Trim();
                            cbMarkets.Items.Add(MarketNames[i]);
                        }
                        cbMarkets.SelectedIndex = 0;
                        break;
                    case "[favorite]":
                        sListFavoritePath = sr.ReadLine().Trim();
                        break;
                    case "[Amplitude]":
                        if (int.Parse(sr.ReadLine()) != nMarket)
                        {
                            MessageBox.Show("[Amplitude]", "Loi doc file config");
                            return;
                        }
                        for (int i = 0; i < nMarket; i++)
                            lstAmplitude.Add(float.Parse(sr.ReadLine().Trim()));
                        break;
                }
            }
            sr.Close();
		}

        private string convertCurrency(string c)
        {
            if (currency == "VN")
                return c.Replace(".", "").Replace(',', '.');
            return c.Replace(",", "");
        }

        private void btnStatistic_Click(object sender, EventArgs e)
        {
            // Cau truc cua bang thong ke:
            // Ma chung khoan   -> # tang       -> % tang       -> # tran -> % tran 
            //                  -> # dung gia   -> % dung gia 
            //                  -> # giam       -> % giam       -> # san  -> % san
            //                  -> # dao chieu tang (> bien do) -> dao chieu giam (> bien do)
            lstCompanies.Clear();
            lvStatistic.Items.Clear();
            // Load danh sach cong ty
            string code, name;
            float  close, max, min, prevClose;

            float thres = (lstAmplitude[cbMarkets.SelectedIndex] - 0.5f) / 100.0f;
            float thresAmp = (lstAmplitude[cbMarkets.SelectedIndex] / 100.0f);
            StreamReader sr = new StreamReader(cbMarkets.Text + "\\listCompanies.txt");
            int idx = 0;

            while (!sr.EndOfStream)
            {
                // load du lieu cua mot ma chung khoan
                code = sr.ReadLine().Trim();
                name = sr.ReadLine().Trim();
                List<Session> lstSession = GetData(cbMarkets.Text, code, dtpFrom.Value, dtpTo.Value);
                // Thong ke
                int count = lstSession.Count-1;
                int iUp, iCeil, iStable, iDown, iFloor, iUpReversal, iDownReversal;
                iUp = iCeil = iStable = iDown = iFloor = iUpReversal = iDownReversal = 0;

                for (int i = 0; i < count; i++)
                {
                    close = lstSession[i].close;
                    max = lstSession[i].max;
                    min = lstSession[i].min;
                    prevClose = lstSession[i + 1].close;

                    if (close > prevClose)
                        iUp++;
                    else if (close < prevClose)
                        iDown++;
                    else if (close == prevClose)
                        iStable++;
                    float ratio = close / prevClose;
                    if ( ratio >  + thres)
                        iCeil++;
                    if (ratio < 1 - thres && ratio > 1 - thresAmp)
                        iFloor++;
                    if ((close - min) / prevClose > thresAmp)
                        iUpReversal++;
                    if ((max - close) / prevClose > thresAmp)
                        iDownReversal++;
                }
                // Hien thi
                lvStatistic.Items.Add(code);
                lvStatistic.Items[idx].SubItems.Add(iUp.ToString());
                lvStatistic.Items[idx].SubItems.Add((100*iUp/(float)count).ToString());
                lvStatistic.Items[idx].SubItems.Add(iCeil.ToString());
                lvStatistic.Items[idx].SubItems.Add((100*iCeil / (float)iUp).ToString());
                lvStatistic.Items[idx].SubItems.Add(iStable.ToString());
                lvStatistic.Items[idx].SubItems.Add((100*iStable / (float)count).ToString());
                lvStatistic.Items[idx].SubItems.Add(iDown.ToString());
                lvStatistic.Items[idx].SubItems.Add((100*iDown / (float)count).ToString());
                lvStatistic.Items[idx].SubItems.Add(iFloor.ToString());
                lvStatistic.Items[idx].SubItems.Add((100 * iFloor / (float)iDown).ToString());
                lvStatistic.Items[idx].SubItems.Add((100 * iUpReversal / (float)count).ToString());
                lvStatistic.Items[idx].SubItems.Add((100 * iDownReversal / (float)count).ToString());
                lvStatistic.Items[idx].SubItems.Add(count.ToString());
                // Xoa data trong bo nho
                lstSession.Clear();
                idx++;
            }
            sr.Close();
        }

        private List<Session> GetData(string market, string code, DateTime from, DateTime to)
        {
            List<Session> lstSession = new List<Session>();
            
            string filePath = market + "\\Updated Data\\" + code + ".txt";
            
            if (!File.Exists(filePath))
            {
                MessageBox.Show("File does not exist", code);
                return lstSession;
            }
            StreamReader sr = new StreamReader(filePath);

            while (!sr.EndOfStream)
            {
                string s = sr.ReadLine().Trim();
                // Neu may tieng Viet
                if (currency.ToUpper() == "VN")
                    s = s.Replace('.', ',');

                if (s != "")
                {
                    string[] strs = s.Split(' ', '\t');
                    Session session = new Session();
                    try
                    {
                        session.date = DateTime.ParseExact(strs[0], "dd/MM/yyyy", null);
                    }
                    catch (Exception exc)
                    {
                        MessageBox.Show(exc.Message, "Error at GetData " + market + "\\Updated Data\\" + code + ".txt");
                        return null;
                    }
                    session.max = float.Parse(strs[1]);
                    session.min = float.Parse(strs[2]);
                    session.close = float.Parse(strs[3]);
                    session.volume = int.Parse(strs[4]);
                    int k1 = DateComapare(from, session.date);
                    int k2 = DateComapare(session.date, to);

                    if (k1 * k2 >= 0)
                        lstSession.Add(session);
                }
            }
            sr.Close();
            return lstSession;
        }

        private int DateComapare(DateTime dt1, DateTime dt2)
        {
            if (dt1.Year == dt2.Year && dt1.DayOfYear == dt2.DayOfYear)
                return 0;
            return dt1.CompareTo(dt2);
        }

        private void lvStatistic_ColumnClick(object sender, ColumnClickEventArgs e)
        {
            // Determine if clicked column is already the column that is being sorted.
            if (e.Column == lvwColumnSorter.SortColumn)
            {
                // Reverse the current sort direction for this column.
                if (lvwColumnSorter.Order == SortOrder.Ascending)
                {
                    lvwColumnSorter.Order = SortOrder.Descending;
                }
                else
                {
                    lvwColumnSorter.Order = SortOrder.Ascending;
                }
            }
            else
            {
                // Set the column number that is to be sorted; default to ascending.
                lvwColumnSorter.SortColumn = e.Column;
                lvwColumnSorter.Order = SortOrder.Ascending;
            }

            // Perform the sort with these new sort options.
            this.lvStatistic.Sort();
        }
    }
}

